package com.zsc.wxapp.services.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zsc.wxapp.constant.EndUserTime;
import com.zsc.wxapp.context.BaseContext;
import com.zsc.wxapp.entity.CustomerOfManager;
import com.zsc.wxapp.entity.User;
import com.zsc.wxapp.entity.dto.*;
import com.zsc.wxapp.entity.vo.*;
import com.zsc.wxapp.exservices.Remote2;
import com.zsc.wxapp.mapper.CollectedDataMapper;
import com.zsc.wxapp.mapper.CustomerOfManagerMapper;
import com.zsc.wxapp.mapper.PrintTaskMapper;
import com.zsc.wxapp.mapper.UserMapper;
import com.zsc.wxapp.result.PageResult;
import com.zsc.wxapp.services.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userinfoMapper;
    @Resource
    private Remote2 remote2;
    @Resource
    private UserMapper userMapper;
    @Resource
    private CollectedDataMapper collectedDataMapper;
    @Resource
    private PrintTaskMapper printTaskMapper;
    @Resource
    private CustomerOfManagerMapper customerOfManagerMapper;


    /**
     * 用户登录
     *
     * @param userLoginDTO 用户登录信息
     * @return Userinfo
     */
    @Override
    public User login(UserLoginDTO userLoginDTO) {
        User user = userinfoMapper.selectUserByPhone(userLoginDTO.getPhone());

        if (user == null) {
            throw new RuntimeException("该手机还没注册账号！");
        }

        String password = userLoginDTO.getPassword();
        if (password.equals(user.getPassword())) {
            //密码正确，登录成功
            return user;
        } else {
            throw new RuntimeException("密码错误！");
        }
    }

    /**
     * 获取用户详细信息
     *
     * @param userId
     * @return userInfoVO
     */
    @Override
    public UserInfoVO getUserInfo(Long userId) {
        //查询本地用户的数据
        User user = userinfoMapper.selectUserById(userId);
        UserInfoVO result;

        if (user.getPermission().equals("1") || user.getPermission().equals("2")) {
            //该用户为一般零售用户
            //根据id查询用户在远程数据库中的唯一标识
            String custUuid = user.getCustomUuid();

            //查询远程数据库，返回我们需要的数据
            CustomerVO customerVO = remote2.getCustomerInfoByCustUuid(custUuid);

            log.info("远程查询结果：{}", customerVO);

            Integer maintenanceTimes = collectedDataMapper.getTimesByUserId(userId, EndUserTime.MAINTENANCE_TIMES) + user.getMaintenanceTimes();
            Integer taskSubmitTimes = collectedDataMapper.getTimesByUserId(userId, EndUserTime.SUBMIT_TIME) + user.getSubmitTimes();
            Integer printServiceTimes = collectedDataMapper.getTimesByUserId(userId, EndUserTime.PRINT_TIMES) + user.getPrintTimes();
            Integer photoTimes = collectedDataMapper.getTimesByUserId(userId, EndUserTime.PHOTO_TIMES) + user.getPhotoTimes();

            result = UserInfoVO.builder()
                    .licenseCode(customerVO.getLicenseCode())
                    .custCode(customerVO.getCustCode())
                    .custName(customerVO.getCustName())
                    .address(customerVO.getAddress())
                    .cigarGrade(customerVO.getCigarGrade())
                    .licenseEndDate(customerVO.getLicenseEndDate())
                    .busiPlace(customerVO.getBusiPlace())
                    .maintenanceTimes(maintenanceTimes)
                    .taskSubmitTimes(taskSubmitTimes)
                    .printServiceTimes(printServiceTimes)
                    .photoTimes(photoTimes)
                    .vipRemainDays(user.getVipRewardDays())
                    .vipRewardDays(user.getVipRewardDays())
                    .build();
        } else if (user.getPermission().equals("3") || user.getPermission().equals("4")) {
            // TODO 目前没有分开季度，数据都是全部的
            Integer customerNum = userMapper.getCustomerNumById(userId);
            // 获取客户专员自己的拍照次数
            Integer oldDate = collectedDataMapper.getTimesByUserId(userId, EndUserTime.PHOTO_TIMES);
            Integer photoTimes = user.getPhotoTimes() + oldDate;
            // 获取客户专员自己维护次数
            Integer oldMaintenanceTimes = collectedDataMapper.getTimesByUserId(userId, EndUserTime.MAINTENANCE_TIMES);
            Integer maintenanceTimes = user.getMaintenanceTimes() + oldMaintenanceTimes;
            // 获取客户专员任务次数
            Integer taskSubmitTimes = printTaskMapper.getTasksNum(userId);
            // 获取用户打印次数
            Integer oldPrintTimes = collectedDataMapper.getTimesByUserId(userId, EndUserTime.PRINT_TIMES);
            Integer printServiceTimes = user.getPrintTimes() + oldPrintTimes;
            // 获取已采集户数
            Integer collectedCustomerNum = userMapper.getCollectedCustomerNum();

            //该用户为客户专员，或者是专卖稽查员
            result = UserInfoVO.builder()
                    // TODO 完善其他用户的数据，目前只有零售用户的数据正常
                    .name(user.getName())
                    .position(user.getPermission())
                    .customerNum(customerNum)
                    .photoTimes(photoTimes)
                    .maintenanceTimes(maintenanceTimes)
                    .taskSubmitTimes(taskSubmitTimes)
                    .printServiceTimes(printServiceTimes)
                    .collectedCustomerNum(collectedCustomerNum)
                    .build();
        } else {
            //该用户为管理员
            Integer customerNum = userMapper.getCustomerNum(0);
            Integer collectedCustomerNum = userMapper.getCustomerNum(1);
            BigDecimal collectionCoverage = BigDecimal.ZERO;
            try {
                collectionCoverage = BigDecimal.valueOf(collectedCustomerNum).divide(BigDecimal.valueOf(customerNum));
            } catch (Exception e) {
                log.error("除数为0");
            }
            result = UserInfoVO.builder()
                    .userId(user.getUserId())
                    .name(user.getName())
                    .profilePhotoUrl(user.getProfilePhotoUrl())
                    .position(null) //TODO 岗位目前为空，没有对应数据
                    .customerNum(customerNum)
                    .collectedCustomerNum(collectedCustomerNum)
                    .collectionCoverage(collectionCoverage)
                    .build();
        }

        return result;
    }

    /**
     * 获取订单列表
     *
     * @param orderPageDTO
     * @return List
     */
    @Override
    public PageResult orderPage(OrderPageDTO orderPageDTO) {
        PageHelper.startPage(orderPageDTO.getPageNum(), 15);
        Page<OrderListVO> page = new Page<>();

        //获取当前用户的uuid
        String custUuid = userMapper.selectUserById(BaseContext.getCurrentId()).getCustomUuid();
        List<OrderVO> list = remote2.getOrderByCustUuid(custUuid);

        if (list == null) return null;

        //定义获取到的第一个订单的标识
        String orderUuid = list.get(0).getOrderUuid();
        List<OrderVO> orderList = new ArrayList<>();

        for (int i = 0; i < list.size(); i++) {
            OrderVO order = list.get(i);

            if (i == list.size() - 1) {

                OrderVO o = new OrderVO();
                BeanUtils.copyProperties(order, o);
                orderList.add(o);

                //遍历到集合的最后一位，直接插入数据到result中
                OrderListVO orderListVO = new OrderListVO();
                orderListVO.setDate(orderList.get(0).getDate());
                orderListVO.setSumQty(orderList.get(0).getQty());
                orderListVO.setSumWithTaxAmt(orderList.get(0).getWithTaxAmt());
                orderListVO.setOrderUuid(orderUuid);
                orderListVO.setOrderList(orderList);
                page.add(orderListVO);
                break;
            }

            if (order.getOrderUuid().equals(orderUuid)) {
                //判断当前的订单是否是同一个
                OrderVO o = new OrderVO();
                BeanUtils.copyProperties(order, o);
                orderList.add(o);
            } else {
                //当前获取到的订单已经不是同一个
                // 创建一个 orderList 的副本并传递给 OrderListVO
                List<OrderVO> orderListCopy = new ArrayList<>(orderList);
                //处理目前目前的list数据
                OrderListVO orderListVO = OrderListVO.builder()
                        .date(orderList.get(0).getDate())
                        .sumQty(orderList.get(0).getQty())
                        .sumWithTaxAmt(orderList.get(0).getWithTaxAmt())
                        .orderUuid(orderUuid)
                        .orderList(orderListCopy)
                        .build();
                page.add(orderListVO);
                //更新uuid值
                orderUuid = order.getOrderUuid();
                //处理本轮的数据
                OrderVO o = new OrderVO();
                BeanUtils.copyProperties(order, o);
                //清空集合
                orderList.clear();
                //插入新的数据
                orderList.add(o);
            }
        }
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 更新用户次数
     *
     * @param type 类型:1是打印次数，2是反馈次数
     */
    @Override
    public void updateUserTimes(Integer type) {
        if (type == 1) {
            userMapper.updateTimes(EndUserTime.PRINT_TIMES, BaseContext.getCurrentId());
        } else if (type == 2) {
            userMapper.updateTimes(EndUserTime.SUBMIT_TIME, BaseContext.getCurrentId());
        }
    }

    /**
     * 更新用户VIP天数
     */
    @Override
    public void updateVipDays(String custUuid) {
        log.info("更新用户VIP天数, custUuid:{}", custUuid);
        if (custUuid.equals("null") || custUuid.equals("") || custUuid.isEmpty()) {
            Long id = BaseContext.getCurrentId();
            log.info("该用户是C端用户， userId:{}", id);
            log.info("修改前的数据是：{}", userMapper.selectUserById(id));
            custUuid = userMapper.selectUserById(id).getCustomUuid();
            userMapper.updateVipDay(custUuid, 1);
            log.info("更新用户VIP天数成功, 新的数据是：{}", userMapper.selectUserById(id).getVipRewardDays());
        } else {
            log.info("该用户为B端用户");
            userMapper.updateVipDay(custUuid, 2);
        }
    }

    /**
     * 获取已注册的客户经理
     *
     * @return
     */
    @Override
    public List<String> getManagerName(Integer type) {
        if (type == 0) {
            List<CustomerOfManager> list = customerOfManagerMapper.getAllManager();
            List<String> result = new ArrayList<>();
            for (CustomerOfManager customerOfManager : list) {
                result.add(customerOfManager.getManagerName());
            }
            return result;
        } else if (type == 1) {
            // 对数据进行处理，筛选出已经客户经理
            List<User> result = userMapper.getAllUser();
            return result.stream()
                    .filter(user -> user.getPermission().equals("3") || user.getPermission().equals("4"))
                    .map(User::getName)
                    .collect(Collectors.toList());
        }
        return null;
    }

    /**
     * 添加客户经理
     *
     * @param addManagerDTO
     * @return
     */
    @Override
    public void addManager(AddManagerDTO addManagerDTO) throws Exception {
        // 判断是否已经注册账号
        List<String> managerList = getManagerName(1);
        boolean isExist = managerList.contains(addManagerDTO.getMangerName());
        if (isExist) {
            throw new Exception("该客户经理已经注册账号");
        }

        String managerUuid = remote2.getManagerByName(addManagerDTO.getMangerName());
        if (managerUuid == null) {
            throw new Exception("系统出错，请联系管理员");
        }
        userMapper.addManager(managerUuid, addManagerDTO.getMangerName(), addManagerDTO.getMangerPhone(), addManagerDTO.getPassword(), LocalDateTime.now());
    }

    /**
     * 获取客户经理所对应的客户
     *
     * @param managerName
     * @return
     */
    @Override
    public List<CustomerOfManagerVO> getEndUserByManager(String managerName) {
        List<CustomerOfManager> list = customerOfManagerMapper.getCustomerByManager(managerName);
        List<CustomerOfManagerVO> result = new ArrayList<>();
        for (CustomerOfManager customerOfManager : list) {
            result.add(new CustomerOfManagerVO(customerOfManager.getLienseCode(), customerOfManager.getShopHead()));
        }
        return result;
    }

    /**
     * 添加零售用户
     *
     * @param addEndUserDTO
     */
    @Override
    public void addEndUser(AddEndUserDTO addEndUserDTO) throws Exception {
        // 校验对应的客户经理是否已经有账号
        List<User> managerList = userMapper.getAllManager();
        boolean managerExist = false;
        Long managerId = 0L;
        for (User user : managerList) {
            if (user.getName().contains(addEndUserDTO.getMangerName())) {
                managerExist = true;
                managerId = user.getUserId();
            }
        }

        if (!managerExist) {
            throw new Exception("该经理还未注册账号");
        }

        // 校验用户是否已经注册
        List<User> userList = userMapper.getAllEndUser(null);
        boolean isLicenseExist = userList.stream()
                .anyMatch(user -> user.getCustomUuid().contains(addEndUserDTO.getLicenseCode()));
        if (isLicenseExist) {
            throw new Exception("该用户已经注册");
        }

        // 校验手机号是否唯一
        boolean isPhoneExist = userList.stream()
                .anyMatch(user -> user.getPhone().equals(addEndUserDTO.getPhone()));
        if (isPhoneExist) {
            throw new Exception("该手机号已经注册");
        }

        // 获取用户信息
        CustomerVO customerVO = remote2.getCustomerByLicenseCode(addEndUserDTO.getLicenseCode());

        // 添加用户
        userMapper.addEndUser(customerVO.getCustUuid(), customerVO.getManagePersonName(), addEndUserDTO.getPhone(),
                addEndUserDTO.getPassword(), customerVO.getCustName(), customerVO.getCustUuid(), LocalDateTime.now(), addEndUserDTO.getArea(), customerVO.getCustTypeName(), managerId);
    }

    /**
     * 分页获取用户数据
     *
     * @param pageSize
     * @param pageNum
     * @param type
     * @return
     */
    @Override
    public PageInfo getAllUser(Integer pageSize, Integer pageNum, Integer type) {
        pageSize = 15;
        List<User> list = null;
        if (type == 0) {
            // 获取零售用户
            PageHelper.startPage(pageNum, pageSize);
            list = userMapper.getAllEndUser(null);
        } else if (type == 1) {
            // 获取经理账号
            PageHelper.startPage(pageNum, pageSize);
            list = userMapper.getAllManager();
        } else
            return null;

        List<UserVO> userList = new ArrayList<>();
        for (User user : list) {
            log.info("用户信息：{}", user);
            if (user.getIsValid() != -1) {
                userList.add(new UserVO(user.getUserId(), user.getName(), user.getIsValid(), user.getPhone()));
            }
        }
        PageInfo<UserVO> result = new PageInfo<>(userList);
        return result;
    }

    /**
     * 设置用户状态
     * @param setStatusDTO
     */
    @Override
    public void setStatus(SetStatusDTO setStatusDTO) {
        // 如果 status 是 -1，直接删除用户并返回
        if (setStatusDTO.getStatus() == -1) {
            userMapper.deleteUser(setStatusDTO.getUserId());
            return;
        }

        // 获取用户当前状态并设置为相反状态
        User user = userMapper.selectUserById(setStatusDTO.getUserId());
        if (user != null) {
            Integer isValid = user.getIsValid();
            if (isValid != null) {
                // 直接设置为相反状态
                userMapper.setStatus(setStatusDTO.getUserId(), isValid == 1 ? 0 : 1);
            }
        }
    }

    /**
     * 修改密码
     * @param modifyInfoDTO
     */
    @Override
    public void modifyPassword(ModifyInfoDTO modifyInfoDTO) {
        userMapper.updateUserInfo(modifyInfoDTO.getUserId(), modifyInfoDTO);
    }

    /**
     * 修改手机号
     * @param modifyInfoDTO
     */
    @Override
    public void modifyPhone(ModifyInfoDTO modifyInfoDTO) {
        userMapper.updateUserInfo(modifyInfoDTO.getUserId(), modifyInfoDTO);
    }
}
